<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
 * CodeIgniter
 *
 * An open source application development framework for PHP 4.3.2 or newer
 *
 * @package  CodeIgniter
 * @author  ExpressionEngine Dev Team
 * @copyright Copyright (c) 2006 - 2012 EllisLab, Inc.
 * @license  http://codeigniter.com/user_guide/license.html
 * @link  http://codeigniter.com
 * @since  Version 2.0
 * @filesource
 */

// ------------------------------------------------------------------------

/**
 * CodeIgniter Memcached Caching Class
 *
 * @package  CodeIgniter
 * @subpackage Libraries
 * @category Core
 * @author  ExpressionEngine Dev Team
 * @link
 */

class CI_Cache_memcached extends CI_Driver {

 private $_memcached; // Holds the memcached object

 protected $_memcache_conf  = array(
      'default' => array(
      'default_host'  => '127.0.0.1',
      'default_port'  => 11211,
      'default_weight' => 1
     )
    );

 // ------------------------------------------------------------------------

 /**
  * Fetch from cache
  *
  * @param  mixed  unique key id
  * @return  mixed  data on success/false on failure
  */
 public function get($id)
 {
  $data = $this->_memcached->get($id);
  return (is_array($data)) ? $data[0] : FALSE;
 }

 // ------------------------------------------------------------------------

 /**
  * Save
  *
  * @param  string  unique identifier
  * @param  mixed  data being cached
  * @param  int   time to live
  * @return  boolean  true on success, false on failure
  */
 public function save($id, $data, $ttl = 60)
 {
  if (get_class($this->_memcached) == 'Memcached')
  {
   return $this->_memcached->set($id, array($data, time(), $ttl), $ttl);
  }
  else if (get_class($this->_memcached) == 'Memcache')
  {
   return $this->_memcached->set($id, array($data, time(), $ttl), 0, $ttl);
  }
  return FALSE;
 }

 // ------------------------------------------------------------------------

 /**
  * Delete from Cache
  *
  * @param  mixed  key to be deleted.
  * @return  boolean  true on success, false on failure
  */
 public function delete($id)
 {
  return $this->_memcached->delete($id);
 }

 // ------------------------------------------------------------------------

 /**
  * Clean the Cache
  *
  * @return  boolean  false on failure/true on success
  */
 public function clean()
 {
  return $this->_memcached->flush();
 }

 // ------------------------------------------------------------------------

 /**
  * Cache Info
  *
  * @param  null  type not supported in memcached
  * @return  mixed   array on success, false on failure
  */
 public function cache_info($type = NULL)
 {
  return $this->_memcached->getStats();
 }

 // ------------------------------------------------------------------------

 /**
  * Get Cache Metadata
  *
  * @param  mixed  key to get cache metadata on
  * @return  mixed  FALSE on failure, array on success.
  */
 public function get_metadata($id)
 {
  $stored = $this->_memcached->get($id);

  if (count($stored) !== 3)
  {
   return FALSE;
  }

  list($data, $time, $ttl) = $stored;

  return array(
   'expire' => $time + $ttl,
   'mtime'  => $time,
   'data'  => $data
  );
 }

 // ------------------------------------------------------------------------

 /**
  * Setup memcached.
  */
 private function _setup_memcached()
 {
  // Try to load memcached server info from the config file.
  $CI =& get_instance();
  if ($CI->config->load('memcached', TRUE, TRUE))
  {
   if (is_array($CI->config->config['memcached']))
   {
    $this->_memcache_conf = NULL;

    foreach ($CI->config->config['memcached'] as $name => $conf)
    {
     $this->_memcache_conf[$name] = $conf;
    }
   }
  }
  if (extension_loaded('memcached')){
   $this->_memcached = new Memcached();
  }else{
   $this->_memcached = new Memcache();
  }


 foreach ($this->_memcache_conf as $name => $cache_server)
 {
           if ( ! array_key_exists('hostname', $cache_server))
            {

               // $cache_server['hostname'] = $this->_default_options['default_host']; //坑爹的原代码,没有_default_options属性
                $cache_server['hostname'] = $this->_memcache_conf['default']['default_host'];
            }

            if ( ! array_key_exists('port', $cache_server))
            {

               // $cache_server['port'] = $this->_default_options['default_port'];//坑爹的原代码,没有_default_options属性
                $cache_server['port'] = $this->_memcache_conf['default']['default_port'];
            }

            if ( ! array_key_exists('weight', $cache_server))
            {

              //  $cache_server['weight'] = $this->_default_options['default_weight'];//坑爹的原代码,没有_default_options属性
                $cache_server['weight'] = $this->_memcache_conf['default']['default_weight'];
            }
             //导致如果不配置 config/memcache.php文件，执行到$this->_memcached->addServer($cache_server['hostname'],$cache_server['port']);出错（因为此时语句，相当于$this->_memcached->addServer(‘’,'');然后机器木反应了~

            if (extension_loaded('memcached')){
                $this->_memcached->addServer(
                    $cache_server['hostname'], $cache_server['port'], $cache_server['weight']
                );
            }else{
                $this->_memcached->addServer($cache_server['hostname'],$cache_server['port'],TRUE, $cache_server['weight']);
            }
    }
 }

 // ------------------------------------------------------------------------

 /**
  * Is supported
  *
  * Returns FALSE if memcached is not supported on the system.
  * If it is, we setup the memcached object & return TRUE
  */
 public function is_supported()
 {

  if ( !extension_loaded('memcached') && !extension_loaded('memcache'))
  {
   log_message('error', 'The Memcached Extension must be loaded to use Memcached Cache.');

   return FALSE;
  }

  $this->_setup_memcached();
  return TRUE;
 }

 // ------------------------------------------------------------------------

}
// End Class

/* End of file Cache_memcached.php */
/* Location: ./system/libraries/Cache/drivers/Cache_memcached.php */